#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// ActionManager.h : interface of the ActionManager class
//


#include "Action.h"
#include "WorldFollower.h"
#include "UiFollower.h"
#include <list>
#include <zthread/zthread.h>



class ActionManager : public WorldFollower,
                      public UiFollower,
                      boost::noncopyable
{
public:

    // ************************************************************************

    ActionManager(World* w, Ui* ui);

    // ************************************************************************

    // Put an action on the queue where it will remain until its 
    // time comes to be performed
    void postAction(ref<Action> action);

    // Takes the first action on the queue and performs. This should be 
    // always called from the same thread or else we defy the purpose of
    // having a queue in the first place
    void performNext();

    // ************************************************************************

    // Perform an action inmediately
    void performAction(ref<Action> action);

    // ************************************************************************

    bool canUndo() const;
    void undo();
    
    // ************************************************************************

    bool canRedo() const;
    void redo();

private:

    ZThread::Mutex m_actionQueueMutex;
    ZThread::LockedQueue<ref<Action>, ZThread::Mutex> m_actionQueue;


    typedef std::list<ref<Action> > ActionList;
    ActionList m_undoActions;
    ActionList m_redoActions;
};
